﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using AIthin.Neuro;

namespace AIthin.Model.Body
{
    public class Wurm
    {
        /// <summary>
        /// input Matrix für NN
        /// </summary>
        short[,] input;
        /// <summary>
        /// output vektor von NN
        /// </summary>
        short[] output;
        public INetwork mind;
        public Actuator muscle;
        Retina retina;
        public bool Dead = false;
        int attentionUpNeuron;
        int attentionDownNeuron;
        int attentionLeftNeuron;
        int attentionRightNeuron;
        int moveLeftNeuron;
        int moveRightNeuron;
        public int damageCapacity { get; protected set; }

        public Wurm(String FileName)
        {
            muscle = new Actuator(64);
            retina = new Retina(32);
            mind = new Network(96, retina.Size * retina.Size, 12);

            attentionUpNeuron = mind.NeuronsCount - 1;
            attentionDownNeuron = mind.NeuronsCount - 2;
            attentionLeftNeuron = mind.NeuronsCount - 3;
            attentionRightNeuron = mind.NeuronsCount - 4;
            moveLeftNeuron = mind.NeuronsCount - 5;
            moveRightNeuron = mind.NeuronsCount - 6;

            damageCapacity = 30;


        }

        public Wurm(INetwork Mind)
        {
            muscle = new Actuator(64);
            retina = new Retina(32);
            mind = Mind;

            attentionUpNeuron = mind.NeuronsCount - 1;
            attentionDownNeuron = mind.NeuronsCount - 2;
            attentionLeftNeuron = mind.NeuronsCount - 3;
            attentionRightNeuron = mind.NeuronsCount - 4;
            moveLeftNeuron = mind.NeuronsCount - 5;
            moveRightNeuron = mind.NeuronsCount - 6;

            damageCapacity = 30;


        }


        public void Reaction(Bitmap bmRealitySnap)
        {

            Graphics g = Graphics.FromImage(bmRealitySnap);

            input = retina.ReadBitmap(bmRealitySnap);
            //prozessing signal für NN
            mind.Tick(ref input);

            retina.Draw(g);

            //wurm moving
            if (mind[moveLeftNeuron].Activated) muscle.links();
            if (mind[moveRightNeuron].Activated) muscle.rechts();

            //retina center
            if (mind[attentionUpNeuron].Activated) retina.up_down(5, bmRealitySnap.Height);
            if (mind[attentionDownNeuron].Activated) retina.up_down(-5, bmRealitySnap.Height);
            if (mind[attentionLeftNeuron].Activated) retina.left_right(-5, bmRealitySnap.Height);
            if (mind[attentionRightNeuron].Activated) retina.left_right(5, bmRealitySnap.Height);

            muscle.Draw(g);
        }
        public void Reaction(ref short[,] inp)
        {

            //          Graphics g = Graphics.FromImage(bmRealitySnap);

            //          input = retina.ReadBitmap(bmRealitySnap);


            //            retina.Draw(g);

            //           output = new short[mind.outputsCount];

            //prozessing signal für NN
            mind.Tick(ref inp);

            //wurm moving
            if (mind[moveLeftNeuron].Activated) muscle.links();
            if (mind[moveRightNeuron].Activated) muscle.rechts();

            //retina center
            /*            if (mind[attentionUpNeuron].Activated) retina.up_down(5,  bmRealitySnap.Height);
                        if (mind[attentionDownNeuron].Activated) retina.up_down(-5, bmRealitySnap.Height);
                        if (mind[attentionLeftNeuron].Activated) retina.left_right(-5, bmRealitySnap.Height);
                        if (mind[attentionRightNeuron].Activated) retina.left_right(5, bmRealitySnap.Height);
            */
            //            muscle.Draw(g);
        }
        /// <summary>
        /// Analysed dead or not dead
        /// </summary>
        /// <returns>true - is dead, false - isn´t dead</returns>
        public bool IsDead()
        {
            if (--damageCapacity > 0)
            {
                return false;
            }
            else
            {
                Dead = true;
                return true;
            }
        }
    }
}
